package com.yswy.backstage.logfilter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Aspect
@Component
public class RestControllerLogAspect {
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    private String reqAddress;


    @Pointcut("execution(public * com.yswy.backstage.controller..*.*(..))")
    public void controllerLog() {
    }

    @Before("controllerLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        reqAddress = request.getRemoteAddr();

        // 只记录post方法
        //if("POST".equals(request.getMethod())){
        // 记录下请求内容
        log.info(reqAddress + " : 请求 URL : " + request.getRequestURL() +
                " 请求方法 : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());


        // 获取参数, 只取自定义的参数, 自带的HttpServletRequest, HttpServletResponse不管
        if (joinPoint.getArgs().length > 0) {
            for (Object o : joinPoint.getArgs()) {
                if (o instanceof HttpServletRequest || o instanceof HttpServletResponse) {
                    continue;
                }
                ObjectMapper oMapper = new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
//                log.info(reqAddress + ": 请求参数 : " + oMapper.writeValueAsString(o));
            }
        }
        //}
    }

    @AfterReturning(returning = "ret", pointcut = "controllerLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求，返回内容
        String result = new ObjectMapper().writeValueAsString(ret);
//        log.info(reqAddress + ": 请求返回 : " + result);
    }

    @AfterThrowing(throwing = "e", value = "controllerLog()")
    public void doAfterThrowing(Throwable e) {
        log.error("异常 : " + e);
    }
}
